<?php

namespace app\api\controller\Appoint;

use app\api\controller\Common;
use app\api\Logic\Campusclass\CampusClassCourseSignLogic;
use app\api\Logic\Campusclass\CampusClassDateRecordLogic;
use app\api\Logic\Campusclass\CampusClassLogic;
use app\api\Logic\Campusclass\ClassCourseLogic;
use app\api\Logic\Course\ManagementLogic;
use app\api\Logic\Course\OrderSublevelLogic;
use app\api\Logic\ManystoreShopSettingLogic;
use app\api\model\CampusClassCourseDateModel;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

/**
 * 班课接口
 */
class ClassCourse extends Common
{
    protected $noNeedLogin = ['*'];

    protected $orderSublevelLogic;
    protected $campusClassLogic;
    protected $managementLogic;
    protected $manystoreShopSettingLogic;
    protected $campusClassDateRecordLogic;
    protected $campusClassCourseSignLogic;
    protected $classCourseLogic;

    public function _initialize()
    {
        parent::_initialize();
        $this->orderSublevelLogic = new OrderSublevelLogic();
        $this->campusClassLogic = new CampusClassLogic();
        $this->managementLogic = new ManagementLogic();
        $this->manystoreShopSettingLogic = new ManystoreShopSettingLogic();
        $this->campusClassDateRecordLogic = new CampusClassDateRecordLogic();
        $this->campusClassCourseSignLogic = new CampusClassCourseSignLogic();
        $this->classCourseLogic = new ClassCourseLogic();
    }

    /**
     * 根据日期段返回是否允许预约
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function dateCourse(){
        if($this->request->isPost()){
            $params = $this->request->param();
            //验证数据
            $params = $this->verifyData($params);

            $startDate = $params['start_date'] ?? '';
            $endDate = $params['end_date'] ?? '';
            if(empty($startDate) || empty($endDate)){
                $this->error('时间必须');
            }

            //获取用户购买的课程
            $myOrderSublevelList = $this->orderSublevelLogic->getCourseList($params, 'gs_id');

            //由于课程存在一对多或者一对一，班课这边只需要一对多的课程，因此进行筛选
            $courseIds = [];
            $list = [];
            foreach ($myOrderSublevelList as $orderSublevel) {
                if ($orderSublevel['management_course']['class_type'] == 1) {
                    $courseIds[] = $orderSublevel['gs_id'];
                }
            }
            if (!empty($courseIds)) {
                //根据课程ID反向查询班级ID
                $classList = $this->campusClassLogic->getClassByCourseIds($params['shop_id'], $courseIds);
                $classIds = !empty($classList) ? array_column($classList, 'id') : [];

                if (!empty($classIds)) {
                    //根据班级ID获取班级课表
                    $list = CampusClassCourseDateModel::whereIn('class_id', $classIds)
                        ->field('id,week,start_time,end_time')
                        ->order('start_time', 'desc')
                        ->select();
                    $list = objToArray($list) ?? [];
                }
            }

            //日期数组
            $dateAry = rangeToDays($startDate,$endDate,true);
            //返回给前端的数据
            $res = [];

            foreach ($dateAry as $key => $date){
                $dateToTime = strtotime($date);

                $res[$key] = [
                    'date' => $date,
                    'time' => $dateToTime,
                    'is_can' => false
                ];
                foreach ($list as $val){
                    $startTime = strtotime(date('Y-m-d',$val['start_time']));
                    $endTime = strtotime(date('Y-m-d 23:59:59',$val['end_time']));
                    if($startTime <= $dateToTime && $endTime >= $dateToTime){
                        $res[$key]['is_can'] = true;
                    }
                }
            }

            if(!empty($res)){
                $this->success('查询成功',$res);
            }
            $this->error('暂无数据',$res);
        }
        $this->error('请求错误');
    }

    //获取班课列表
    public function getList()
    {
        if ($this->request->isPost()) {
            $params = $this->request->param();
            //验证数据
            $params = $this->verifyData($params);
            //今日时间
            $date = $params['date'] ?? '';
            $time = !empty($date) ? strtotime(date("Y-m-d", strtotime($date))) : 0;
            //周几
            $week = !empty($time) ? date("w", $time) : 0;

            //获取用户购买的课程
            $myOrderSublevelList = $this->orderSublevelLogic->getCourseList($params, 'gs_id');

            //由于课程存在一对多或者一对一，班课这边只需要一对多的课程，因此进行筛选
            $courseIds = [];
            foreach ($myOrderSublevelList as $orderSublevel) {
                if ($orderSublevel['management_course']['class_type'] == 1) {
                    $courseIds[] = $orderSublevel['gs_id'];
                }
            }
            if (empty($courseIds)) {
                $this->error('暂无数据');
            }

            //根据课程ID反向查询班级ID
            $classList = $this->campusClassLogic->getClassByCourseIds($params['shop_id'], $courseIds);
            $classIds = !empty($classList) ? array_column($classList, 'id') : [];
            if (empty($classIds)) {
                $this->error('暂无数据');
            }

            //根据班级ID获取班级课表
            $list = CampusClassCourseDateModel::whereIn('class_id', $classIds)
                ->with([
                    'classInfo' => function ($query) {
                        $query->withField('id,name');
                    },
                    'classRoom' => function ($query) {
                        $query->withField('id,name');
                    },
                    'teacherInfo' => function ($query) {
                        $query->withField('id,username,nickname')
                            ->where('level', 2);
                    }
                ]);

            //根据日期筛选课表
            if(!empty($time)){
                $list = $list->where('start_time','<=',$time)
                    ->where('end_time','>=',$time)
                    ->where('week',$week);
            }

            $list = $list->field('id,class_id,week,start_time,end_time,teacher_id,classroom_id,status,create_time,sign_time,sign_teacher')
                ->order('start_time', 'desc')
                ->paginate(PAGE_SIZE);
            $list = objToArray($list) ?? [];

            foreach ($list['data'] as $key => $val) {
                //根据班级获取第一个课程用于展示
                $classInfo = $this->campusClassLogic->getInfo($params['shop_id'], $val['class_id']);
                $courseIds = !empty($classInfo['course_id']) ? explode(',', $classInfo['course_id']) : [];

                $list['data'][$key]['course_info'] = [];
                if (isset($courseIds[0]) && !empty($courseIds[0])) {
                    //根据课程ID获取课程详情
                    $courseInfo = $this->managementLogic->managementInfo($courseIds[0]);
                    $list['data'][$key]['course_info'] = $courseInfo;
                }
            }

            if (!empty($list)) {
                $this->success('查询成功', $list);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 班课详情
     */
    public function info()
    {
        if ($this->request->isPost()) {
            $params = $this->request->param();
            //验证数据
            $params = $this->verifyData($params);

            //班课ID
            $classCourseDateId = $params['class_course_date_id'] ?? 0;
            if (empty($classCourseDateId)) {
                $this->error('班课ID必须');
            }

            //根据班课ID获取班级课表
            $info = $this->classCourseLogic->getInfo($classCourseDateId);
            if (empty($info)) {
                $this->error('暂无数据');
            }

            //根据班级获取第一个课程用于展示
            $classInfo = $this->campusClassLogic->getInfo($params['shop_id'], $info['class_id']);
            $courseIds = !empty($classInfo['course_id']) ? explode(',', $classInfo['course_id']) : [];

            $info['course_info'] = [];
            if (isset($courseIds[0]) && !empty($courseIds[0])) {
                //根据课程ID获取课程详情
                $courseInfo = $this->managementLogic->managementInfo($courseIds[0]);
                $info['course_info'] = $courseInfo;
            }

            //获取约课规则
            $info['rule_info'] = $this->manystoreShopSettingLogic->ruleInfo($params['shop_id']);

            //根据约课规则判断学院是否允许预约
            $info['is_can'] = $this->manystoreShopSettingLogic->verifyRule($params['shop_id'], $params['user_id'], $info);

            $this->success('查询成功', $info);
        }
        $this->error('请求错误');
    }

    /**
     * 约课
     */
    public function reserveClassCourse()
    {
        if ($this->request->isPost()) {
            $params = $this->request->param();
            //验证数据
            $params = $this->verifyData($params);

            //班课ID
            $classCourseDateId = $params['class_course_date_id'] ?? 0;
            if (empty($classCourseDateId)) {
                $this->error('班课ID必须');
            }

            //根据班课ID获取班级课表
            $info = $this->classCourseLogic->getInfo($classCourseDateId);
            if (empty($info)) {
                $this->error('暂无数据');
            }

            //根据约课规则判断学员是否允许预约
            $isCan = $this->manystoreShopSettingLogic->verifyRule($params['shop_id'], $params['user_id'], $info);
            if (!$isCan) {
                $this->error('该学员无法预约该课程');
            }

            //判断当前学员预约是否需要排队，若需排队，则生成一条未约上的预约记录，否则生成
            $isLineUp = false;  //是否需要排队
            $records = $this->campusClassDateRecordLogic->getRecordList(['class_id' => $info['class_id'], 'date_id' => $info['id'], 'status' => 1]);
            if (count($records) >= $info['class_info']['class_size']) {
                //已成功预约学员数大于等于班级规模，则需要排队
                $isLineUp = true;
            }

            Db::startTrans();
            try {
                if ($isLineUp) {
                    //需要排队，则添加排队记录
                    $this->campusClassDateRecordLogic->insert([
                        'shop_id' => $params['shop_id'],
                        'user_id' => $params['user_id'],
                        'class_id' => $info['class_id'],
                        'date_id' => $info['id'],
                        'status' => 0
                    ]);
                } else {
                    //无需排队，除了添加排队记录，还需添加预约成功记录
                    $recordId = $this->campusClassDateRecordLogic->insert([
                        'shop_id' => $params['shop_id'],
                        'user_id' => $params['user_id'],
                        'class_id' => $info['class_id'],
                        'date_id' => $info['id'],
                        'status' => 1
                    ]);
                    //添加预约成功记录
                    $this->campusClassCourseSignLogic->insert([
                        'a_id' => $info['a_id'],
                        'shop_id' => $info['shop_id'],
                        'd_id' => $info['id'],
                        'user_id' => $params['user_id'],
                        'class_id' => $info['class_id'],
                        'record_id' => $recordId,
                        'week' => $info['week'],
                        'start_time' => $info['start_time'],
                        'end_time' => $info['end_time'],
                        'teacher_id' => $info['teacher_id'],
                        'classroom_id' => $info['classroom_id']
                    ]);
                }

                Db::commit();
                $this->success('预约成功');
            } catch (Exception $e) {
                Db::rollback();
                $this->error('预约失败');
            }
        }
        $this->error('请求错误');
    }
}
